<template>
  <div style="border: 1px solid #ccc" v-loading="loading">
    <Toolbar
      style="border-bottom: 1px solid #ccc;"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor 
      style="min-height: 100px; overflow-y: hidden; text-align: left;"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
      @onChange="handleChange"
    />
  </div>
</template>
<script setup>
// "@wangeditor/editor": "^5.1.23",
// "@wangeditor/editor-for-vue": "^5.1.12",
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { uploadFile } from '@/api/global/index';
import { urlHead } from '@/api';

// 初始值
const props = defineProps({
  /* 编辑器的内容 */
  modelValue: {
    type: String,
  },
  /* 高度 */
  height: {
    type: Number,
    default: null,
  },
  /* 最小高度 */
  minHeight: {
    type: Number,
    default: null,
  },
  /* 只读 */
  readOnly: {
    type: Boolean,
    default: false,
  },
  /* 上传文件大小限制(MB) */
  fileSize: {
    type: Number,
    default: 5,
  },
  /* 类型（base64格式、url格式） */
  type: {
    type: String,
    default: 'url',
  },
});

const emits = defineEmits(['getEditorContent']);
// const emits = defineEmits([''])
let mode = ref('default');
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();
// 内容 HTML
const valueHtml = ref('');
const loading = ref(false)

watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue !== valueHtml.value) {
      valueHtml.value = newValue || '';
    }
  },
  { immediate: true, deep: true }
);

// 工具栏配置
const toolbarConfig = {
  toolbarKeys: [
    // 菜单 key
    'headerSelect',
    'bold', // 加粗
    'italic', // 斜体
    'through', // 删除线
    'underline', // 下划线
    'bulletedList', // 无序列表
    'numberedList', // 有序列表
    'color', // 文字颜色
    'insertLink', // 插入链接
    'fontSize', // 字体大小
    'lineHeight', // 行高
    'uploadImage', // 上传图片
    // 'delIndent', // 缩进
    'indent', // 增进
    // 'deleteImage', //删除图片
    'divider', // 分割线
    'insertTable', // 插入表格
    'justifyLeft', // 左对齐
    'justifyCenter', // 居中对齐
    'justifyRight', // 右对齐
    // 'justifyJustify', // 两端对齐
    'undo', // 撤销
    // 'redo', // 重做
    'clearStyle', // 清除格式
    // 'fullScreen', // 全屏
  ],
};
const editorConfig = {
  placeholder: 'Please enter content...', // 配置默认提示
  // readOnly: true,
  MENU_CONF: {
    // 配置上传服务器地址
    uploadImage: {
      // 小于该值就插入 base64 格式（而不上传），默认为 0
      base64LimitSize: 5 * 1024, // 5kb
      // 单个文件的最大体积限制，默认为 2M
      // maxFileSize: 1 * 1024 * 1024, // 1M
      // // 最多可上传几个文件，默认为 100
      // maxNumberOfFiles: 5,
      // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
      allowedFileTypes: ['image/*'],
      // 自定义上传
      async customUpload(file, insertFn) {
        loading.value = true;
        // 文件上传
        const formData = new FormData();

        formData.append('file', file);

        uploadFile(formData).then((result) => {
            // 插入到富文本编辑器中，主意这里的三个参数都是必填的，要不然控制台报错：typeError: Cannot read properties of undefined (reading 'replace')
            insertFn(
              urlHead + result.data.filePath,
              result.data.fileName + result.data.extName,
              result.data.filePath
            );
            editorRef.value.focus();
          })
          .finally(() => {
            loading.value = false;
          });
      },
    },
  },
};
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});
const handleCreated = (editor) => {
  editorRef.value = editor; // 创建富文本编辑器
};
const handleChange = (info) => {
  valueHtml.value = valueHtml.value
    .replace(/<table style="/g, '<table style="border-collapse:collapse;')
    .replace(/<table /g, '<table border="1" ');

  // info.children 数组包含了数据类型和内容，valueHtml.value内容的html格式
  emits('getEditorContent', info.children, valueHtml.value);
  emits('update:modelValue', valueHtml.value)
};
function insertEmoji(emi) {
  if (emi) {
    // 重新聚焦编辑器
    editorRef.value.focus();
    editorRef.value.insertText(emi);
  }
}
watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue !== valueHtml.value) {
      valueHtml.value = newValue || '';
    }
  }, { immediate: true, deep: true, }
);

defineExpose({
  insertEmoji,
})
</script>

<style lang="scss" scoped>
// 样式变量需要去index.scss中定义
::v-deep .w-e-text-container{
    // color: #999999;
}
</style>
